package com.dhms.vostok1.ui.main.home

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.paging.LoadState
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.viewpager2.widget.ViewPager2
import com.dhms.home.R


import com.dhms.home.databinding.FragmentHomeBinding
import com.dhms.uikit.SpacesItemDecoration
import com.dhms.uikit.qrCodeScan.QRCodeScanActivity
import com.dhms.vostok1.adapter.ToDoCenterListAdapter
import com.dhms.vostok1.adapter.TodoListStatisticsViewPager
import com.dhms.vostok1.data.device_center.DeviceListItemData
import com.dhms.vostok1.data.maintenance.TaskModuleType
import com.dhms.vostok1.data.todo.ToDoBizType
import com.dhms.vostok1.data.todo.ToDoCenterData
import com.dhms.vostok1.model.DeviceViewModel
import com.dhms.vostok1.model.DeviceViewModel.Companion.DEVICE_STATE_RUNNING
import com.dhms.vostok1.model.DeviceViewModel.Companion.DEVICE_STATE_STOP
import com.dhms.vostok1.model.DeviceViewModel.Companion.DEVICE_STATE_UNKNOWN
import com.dhms.vostok1.model.HomeViewModel
import com.dhms.vostok1.model.UserViewModel
import com.dhms.vostok1.model.WebSocketViewModel
import com.dhms.vostok1.ui.main.MainActivityInterface
import com.dhms.vostok1.utils.AppFeatureManager
import com.dhms.vostok1.utils.AppFeatureManager.Companion.faultUrl
import com.dhms.vostok1.utils.AppFeatureManager.Companion.perilUrl
import com.dhms.vostok1.utils.NetworkState
import com.dhms.vostok1.utils.Utils
import com.google.zxing.client.android.Intents
import com.journeyapps.barcodescanner.ScanContract
import com.journeyapps.barcodescanner.ScanIntentResult
import com.journeyapps.barcodescanner.ScanOptions
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch

class HomeFragment : Fragment() {

    private var _binding: FragmentHomeBinding? = null
    private val binding get() = _binding!!
    private var todoLastPosition: Int = -1

    private val userViewModel: UserViewModel by activityViewModels()
    private val deviceViewModel: DeviceViewModel by activityViewModels()
    private val homeViewModel: HomeViewModel by activityViewModels()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentHomeBinding.inflate(inflater, container, false)

        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        binding.lifecycleOwner = viewLifecycleOwner
        binding.userViewModel = userViewModel
        binding.homeViewModel = homeViewModel

        setToolBar()

        bindClickEvent()

        setDeviceStateStatisticsCard()

        setTodoStatistics()

        setToDoList()

        if (WebSocketViewModel.instance.networkChange.value == NetworkState.NETWORK) {
            getStatisticsData()
        }

        binding.alertBannerView.binding.buttonOption = {
            if (WebSocketViewModel.instance.networkChange.value == NetworkState.NETWORK_NO) {
                errorTip(getString(R.string.offline_mode_unavailable))
            } else {
                findNavController().navigate(spotPatrolSynchronizeTaskAction)
            }
        }
    }

    private fun bindClickEvent() {
        binding.dangerStatisticWrapper.setOnClickListener {
            if (WebSocketViewModel.instance.networkChange.value == NetworkState.NETWORK_NO) {
                errorTip(getString(R.string.offline_mode_unavailable))
            } else {
                findNavController().navigate(dangerManagementAction)
            }
        }
        binding.faultStatisticWrapper.setOnClickListener {
            if (WebSocketViewModel.instance.networkChange.value == NetworkState.NETWORK_NO) {
                errorTip(getString(R.string.offline_mode_unavailable))
            } else {
                findNavController().navigate(faultManagementAction)
            }
        }
    }

    private fun getStatisticsData() {
        deviceViewModel.getDeviceStateStatisticData()
        homeViewModel.getTodoOverhaulsCount()
        homeViewModel.getTodoDangersAndFaultsCount()
        homeViewModel.getTodoSpotPatrolsCount()
        homeViewModel.getTodoLubricationCount()
        homeViewModel.getTodoMaintenanceCount()
        homeViewModel.getToDoStatistics()
        homeViewModel.getTodoCenterList()
    }

    private fun setDeviceStateStatisticsCard() {
        deviceViewModel.deviceStateStatisticData.observe(viewLifecycleOwner) {
            binding.runningDeviceCount = it?.get(DEVICE_STATE_RUNNING)?.toString() ?: "--"
            binding.stopDeviceCount = it?.get(DEVICE_STATE_STOP)?.toString() ?: "--"
            binding.offlineDeviceCount = it?.get(DEVICE_STATE_UNKNOWN)?.toString() ?: "--"
        }

//        binding.deviceStatusRunningWrapper.setOnClickListener {
//            (activity as MainActivity).binding.bottomNavigation.selectedItemId =
//                R.id.deviceCenterFragment
//            deviceViewModel.setDeviceListFilters(
//                mapOf(
//                    "deShowStatus" to DEVICE_STATE_RUNNING.toString()
//                )
//            )
//        }
//        binding.deviceStatusStopWrapper.setOnClickListener {
//            (activity as MainActivity).binding.bottomNavigation.selectedItemId =
//                R.id.deviceCenterFragment
//            deviceViewModel.setDeviceListFilters(
//                mapOf(
//                    "deShowStatus" to DEVICE_STATE_STOP.toString()
//                )
//            )
//        }
//        binding.deviceStatusOfflineWrapper.setOnClickListener {
//            (activity as MainActivity).binding.bottomNavigation.selectedItemId =
//                R.id.deviceCenterFragment
//            deviceViewModel.setDeviceListFilters(
//                mapOf(
//                    "deShowStatus" to DEVICE_STATE_UNKNOWN.toString()
//                )
//            )
//        }
    }

    private fun setToDoList() {

        val toDoCenterListAdapter = ToDoCenterListAdapter { toDoCenterData ->
            toDoCenterData?.let {
                todoJump(it)
            }
        }

        binding.todoListRecyclerView.layoutManager = LinearLayoutManager(context)
        binding.todoListRecyclerView.adapter = toDoCenterListAdapter
        binding.todoListRecyclerView.addItemDecoration(
            SpacesItemDecoration(
                resources.getDimension(R.dimen.page_space),
                resources.getDimension(com.dhms.uikit.R.dimen.list_item_divider_space)
            )
        )

        toDoCenterListAdapter.addLoadStateListener {
            binding.todoListLoadingState.visibility =
                if (it.source.refresh is LoadState.Loading) View.VISIBLE else View.GONE
            if (it.source.refresh is LoadState.NotLoading && it.append.endOfPaginationReached && toDoCenterListAdapter.itemCount < 1) {
                binding.noData.root.visibility = View.VISIBLE
            } else {
                binding.noData.root.visibility = View.GONE
            }
        }

        lifecycleScope.launch {
            homeViewModel.getTodoCenterList().collectLatest {
                toDoCenterListAdapter.submitData(it)
            }
        }

    }

    private fun setToolBar() {
        (activity as MainActivityInterface).setNotificationBadge(binding.topAppBar)
        binding.topAppBar.setOnMenuItemClickListener {
            if (WebSocketViewModel.instance.networkChange.value == NetworkState.NETWORK_NO) {
                errorTip(getString(R.string.offline_mode_unavailable))
                false
            } else {
                when (it.itemId) {
                    com.dhms.home.R.id.menu_notification -> {
                        findNavController().navigate(R.id.action_homeFragment_to_messageCenterFragment)
                        true
                    }
                    com.dhms.home.R.id.menu_scanning_qr_code -> {
                        val options =
                            ScanOptions().setCaptureActivity(QRCodeScanActivity::class.java)
                        barcodeLauncher.launch(options)

                        true
                    }
                    com.dhms.home.R.id.menu_nearby_equipment -> {
                        findNavController().navigate(R.id.action_homeFragment_to_nearbyDevicesFragment)
                        true
                    }
                    else -> false
                }
            }
        }
    }


    private fun setTodoStatistics() {
        val todoListViewPager = binding.todoListViewPager
        val indicatorWrapper = binding.todoListIndicatorWrapper

        val indicatorLayoutParams = LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT
        )
        indicatorLayoutParams.marginEnd =
            resources.getDimension(R.dimen.todo_indicator_space).toInt()

        todoListViewPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {

            // 滚动设置底部指示器
            override fun onPageSelected(position: Int) {
                super.onPageSelected(position)

                if (todoLastPosition != -1) {
                    indicatorWrapper.getChildAt(todoLastPosition)
                        ?.setBackgroundResource(R.drawable.ic_home_todo_indicator_inactivied)
                }
                indicatorWrapper.getChildAt(position)
                    .setBackgroundResource(R.drawable.ic_home_todo_indicator)

                todoLastPosition = position
            }
        })


        homeViewModel.toDoStatistics.observe(viewLifecycleOwner) {
            val listSize = it.size
            todoListViewPager.adapter = TodoListStatisticsViewPager(it) {
                if (WebSocketViewModel.instance.networkChange.value == NetworkState.NETWORK_NO) {
                    errorTip(getString(R.string.offline_mode_unavailable))
                } else {
                    findNavController().navigate(toDoCenterAction)
                }
            }

            indicatorWrapper.removeAllViews()

            // 底部指示器
            for (i in 0 until listSize) {
                val tmpImgView = ImageView(requireContext())
                tmpImgView.setBackgroundResource(if (i == 0) R.drawable.ic_home_todo_indicator else R.drawable.ic_home_todo_indicator_inactivied)
                tmpImgView.layoutParams = indicatorLayoutParams

                tmpImgView.setOnClickListener {
                    todoListViewPager.setCurrentItem(i, true)
                }

                indicatorWrapper.addView(tmpImgView)
            }
        }

    }

    private fun todoJump(todoCenterData: ToDoCenterData) {
        if (WebSocketViewModel.instance.networkChange.value == NetworkState.NETWORK_NO) {
            errorTip(getString(R.string.offline_mode_unavailable))
            return
        }
        todoCenterData.bizType?.let {
            when (it) {
                ToDoBizType.MAINTENANCE_TASK, ToDoBizType.LUBRICATION_TASK -> {
                    val taskType =
                        if (it == ToDoBizType.MAINTENANCE_TASK) TaskModuleType.MAINTENANCE else TaskModuleType.LUBRICATION
                    todoCenterData.id?.let { id ->
                        val action =
                            HomeFragmentDirections.actionHomeFragmentToLubricationTaskDetailFragment(
                                id,
                                taskType
                            )
                        findNavController().navigate(action)
                    }
                }
                ToDoBizType.SPOT_PATROL_TASK -> {
                    todoCenterData.id?.split("-")?.let { list ->
                        if (list.count() >= 2) {
                            val action =
                                HomeFragmentDirections.actionHomeFragmentToTaskDetailFragment(
                                    list[0],
                                    list[1].toLong()
                                )
                            findNavController().navigate(action)
                        }
                    }
                }
                else -> {
                    todoCenterData.id?.let { id ->
                        ToDoBizType.getAppUrl(it, id)?.let { url ->
                            val action =
                                HomeFragmentDirections.actionHomeFragmentToWebViewFragment(url)
                            findNavController().navigate(action)
                        }
                    }
                }
            }
        }
    }


    private val barcodeLauncher = registerForActivityResult(
        ScanContract()
    ) { result: ScanIntentResult ->
        if (result.contents == null) {
            val originalIntent = result.originalIntent
            if (originalIntent == null) {
                Log.d(TAG, "Cancelled scan")
            } else if (originalIntent.hasExtra(Intents.Scan.MISSING_CAMERA_PERMISSION)) {
                Log.d(
                    TAG,
                    "Cancelled scan due to missing camera permission"
                )
                Toast.makeText(
                    activity,
                    "请打开相机权限",
                    Toast.LENGTH_LONG
                ).show()
            }
        } else {
            Log.d(TAG, "Scanned")

            val deviceId = Utils.getQueryParameter(result.contents, Utils.deviceId)?.toLongOrNull()
            if (deviceId == null) {
                (activity as MainActivityInterface).showToast(
                    message = "获取不到设备id",
                )
                return@registerForActivityResult
            }

            (activity as MainActivityInterface).showToast(
                message = "正在获取设备信息",
                isLoading = true,
                timeOut = 15
            )

            deviceViewModel.getDeviceByDeviceId(deviceId) {
                (activity as MainActivityInterface).hideToast()
                if (it == null) {
                    (activity as MainActivityInterface).showToast(
                        message = "获取设备信息失败",
                    )
                } else {
                    deviceDetailJump(it)
                }
            }

        }
    }

    private fun deviceDetailJump(deviceData: DeviceListItemData) {
        deviceViewModel.setCurrentDevice(deviceData)
        deviceViewModel.clearDevicePartsData()
        val url = "${AppFeatureManager.deviceDetailUrl}?deviceId=${deviceData.deId}"
        val action =
            HomeFragmentDirections.actionHomeFragmentToWebViewFragment(url)
        findNavController().navigate(action)

    }

    private fun errorTip(message: String?) {
        (activity as MainActivityInterface).showToast(
            R.drawable.ic_fail,
            message,
            false,
            2
        )
    }

    companion object {
        const val TAG = "HomeFragment"
        val dangerManagementAction =
            HomeFragmentDirections.actionHomeFragmentToWebViewFragment(perilUrl)
        val faultManagementAction =
            HomeFragmentDirections.actionHomeFragmentToWebViewFragment(faultUrl)
        val spotPatrolSynchronizeTaskAction =
            HomeFragmentDirections.actionHomeFragmentToSpotPatrolSynchronizeTaskFragment()
        val toDoCenterAction = HomeFragmentDirections.actionHomeFragmentToToDoCenterFragment()
    }
}
